import { ref } from 'vue';
import { getAppEnvConfig } from '/@/utils/env.ts';
import { useUserStore } from '/@/store/modules/user.ts';
import { getAuthCache } from '/@/utils/auth.ts';
import { TOKEN_KEY } from '/@/enum/cacheEnum.ts';
import { useRouter } from 'vue-router';

const router = useRouter();
const userStore = useUserStore();
const { token } = userStore;
const { VITE_GLOB_API_YIN_JI, VITE_GLOB_API_JIAN_CE, VITE_GLOB_API_XIAN_YUN, VITE_GLOB_API_YIN_CHUAN } = getAppEnvConfig();
//健康监测工具报警
export const basicPath = VITE_GLOB_API_YIN_JI;
//应急求助、120
export const emergencyPath = VITE_GLOB_API_JIAN_CE;
//西安云坐席
export const xianYunPath = VITE_GLOB_API_XIAN_YUN;
//银川
export const yinChuanPath = VITE_GLOB_API_YIN_CHUAN;
let t = token || getAuthCache(TOKEN_KEY);

/**
 *
 * @param p websocket地址
 * @param hasTimestamp 是否需要时间戳
 */
export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
    const socket = ref();
    let socketData = ref({});
    let lockReconnect = ref(false); //避免ws重复连接
    const path = ref(p);

    function reconnect(path) {
        if (lockReconnect.value) return;
        lockReconnect.value = true;
        setTimeout(function () {
            //没连接上会一直重连，设置延迟避免请求过多
            init(path);
            lockReconnect.value = false;
        }, 2000);
    }

    //心跳检测
    const heartCheck = {
        timeout: 1000 * 50, //50s发一次心跳
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function () {
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function () {
            let self = this;
            this.timeoutObj = setTimeout(function () {
                //这里发送一个心跳，后端收到后，返回一个心跳消息，
                //onmessage拿到返回的心跳就说明连接正常
                if (socket.value.readyState === WebSocket.OPEN) {
                    //console.log('连接正常' + new Date().toLocaleString());
                    socket.value.send('ping');
                } else {
                    //console.log('连接断开');
                    init();
                }
                self.serverTimeoutObj = setTimeout(function () {
                    //如果超过一定时间还没重置，说明后端主动断开了
                    // TODO
                    // socket.value.close(); //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                }, self.timeout);
            }, this.timeout);
        },
    };

    function init() {
        if (!t) {
            return router?.replace('/login');
        }
        if (typeof WebSocket === 'undefined') {
            alert('您的浏览器不支持socket');
        } else {
            closeSocket();
            // 实例化socket
            //判断是否需要时间戳
            if (hasTimestamp) {
                socket.value = new WebSocket(path.value + Date.now(), [t]);
            } else {
                socket.value = new WebSocket(path.value, [t]);
            }

            socket.value.onclose = function () {
                reconnect(path.value);
                // //console.log('连接关闭', new Date().toLocaleString());
            };
            socket.value.onerror = function () {
                reconnect(path.value);
                console.warn('连接错误');
            };
            socket.value.onopen = function () {
                heartCheck.reset().start(); //心跳检测重置
                // //console.log('连接成功:' + new Date().toLocaleString());
            };
            socket.value.onmessage = function (event) {
                //如果获取到消息，心跳检测重置
                heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
                console.log('收到消息:', event.data);
                if (event.data != 'pong') {
                    let data = JSON.parse(event.data);
                    // socketData.value = data;
                    setSocketData(data);
                }
            };
        }
    }

    function setSocketData(data) {
        socketData.value = data;
    }

    init();

    function closeSocket() {
        socket.value && socket.value.hasOwnProperty('close') && socket.value.close();
    }

    return { socket, socketData, setSocketData, closeSocket };
}
